﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace Game.Surface
{
    public class ExplosionDecorator : SurfaceFieldDecorator
    {
        public static readonly DependencyProperty AgeProperty = DependencyProperty.Register(
            "Age", typeof(Double), typeof(ExplosionDecorator),
            new FrameworkPropertyMetadata(
                0d,
                FrameworkPropertyMetadataOptions.AffectsRender,
                new PropertyChangedCallback(OnAgeChanged),
                null
               )
           );

        static void OnAgeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var p = d as ExplosionDecorator;
            Debug.Assert(p != null, "p != null");
            p.Update();
        }

        public static double GetAge(ExplosionDecorator element)
        {
            return (double)element.GetValue(AgeProperty);
        }

        public static void SetAge(ExplosionDecorator element, double value)
        {
            element.SetValue(AgeProperty, value);
        }

        static BitmapImage[] _Images;

        static ExplosionDecorator()
        {
            Init();
        }
        
        readonly Random _Random = new Random(Environment.TickCount);
        readonly List<Point> _RandomPoints = new List<Point>();

        public ExplosionDecorator(AbstractField field)
            : base(field)
        {
            for(int i = 0; i < 10; i++)
            {
                Point point = new Point(_Random.Next(20, 80), _Random.Next(0, 30));
                _RandomPoints.Add(point);
            }
            StartAutomation(0, 17, 3);
        }

        public Transform RenderTransform { get; set; }

        public static void Init()
        {
            _Images = new[]
            {
                ExplosionImages.Image1,
                ExplosionImages.Image2,
                ExplosionImages.Image3,
                ExplosionImages.Image4,
                ExplosionImages.Image5,
                ExplosionImages.Image6,
                ExplosionImages.Image7,
                ExplosionImages.Image8,
                ExplosionImages.Image9,
                ExplosionImages.Image10,
                ExplosionImages.Image11,
                ExplosionImages.Image12,
                ExplosionImages.Image13,
                ExplosionImages.Image14,
                ExplosionImages.Image15,
                ExplosionImages.Image16,
                ExplosionImages.Image17,
                ExplosionImages.Image18
            };
        }

        public override Brush Decorate(Brush brush)
        {
            DrawingVisual drawingVisual = new DrawingVisual();
            DrawingContext drawingContext = drawingVisual.RenderOpen();

            var bitmap = new RenderTargetBitmap(
                100, 100, 96, 96, PixelFormats.Pbgra32);
            
            double age = GetAge(this);
            var index = (int)age;
            ImageSource source = _Images[index];

            drawingContext.DrawRectangle(
                brush, new Pen(), new Rect(0, 0, 100, 100));
            
            foreach(Point point in _RandomPoints)
            {
                DrawExplosion(drawingVisual, drawingContext, source, point);
            }

            drawingContext.Close();
            return new VisualBrush{ Visual = drawingVisual };
        }

        void DrawExplosion(
            DrawingVisual drawingVisual, 
            DrawingContext drawingContext, 
            ImageSource source, 
            Point offset)
        {
            ScaleTransform t = new ScaleTransform(0.4, 0.4);
            
            TranslateTransform tt = new TranslateTransform(10 + offset.X, 10 + offset.Y);
            drawingContext.PushTransform(t);
            drawingContext.PushTransform(tt);
            
            drawingContext.DrawRectangle(new ImageBrush(source), new Pen(), new Rect(0, 0, 100, 100));
            
            drawingContext.Pop();
        }

        public void StartAutomation(double start, double end, double time)
        {
            var a = new DoubleAnimation {From = start, To = end};

            var duration = new Duration(TimeSpan.FromSeconds(time));
            a.Duration = duration;

            var sb = new Storyboard {Duration = duration};
            sb.Children.Add(a);

            Storyboard.SetTarget(a, this);
            Storyboard.SetTargetProperty(a, new PropertyPath("Age"));

            sb.Completed += delegate
            {
                AbstractField.Decorators.Remove(this);
                AbstractField.Update(true);
            };
            
            sb.Begin();
        }

    }
}
